import * as fs from 'fs';
import * as path from 'path';
import {ServerConfig} from '../types';
import {Logger} from './Logger';
import {MergeUtil} from "./MergeUtil";

// 默认配置
export const DEFAULT_CONFIG: ServerConfig = {
  port: 8080,
  directory: process.cwd(),
  compress: false,
  cors: false,
  cacheMaxAge: 3600,
  proxyRules: {},
  openBrowser: false,

  // 目录浏览页配置
  directoryBrowsing: {
    enabled: true,
    title: '目录列表: {path}',
    showIcons: true,
    showStats: true,
    showFooter: true,
    footerText: '由 NGate 静态文件服务器提供服务',
    customCSS: '',
    sortBy: 'name',
    sortOrder: 'asc',
    showHiddenFiles: false
  },

  // 错误页面配置
  errorPages: {
    notFound: '',
    serverError: ''
  },

  // 日志配置
  logging: {
    level: 'info',
    outputToFile: false,
    filePath: './ngate-access.log',
    format: 'simple',
    colorize: true
  },

  // 安全配置
  security: {
    basicAuth: {
      enabled: false,
      username: '',
      password: ''
    },
    https: {
      enabled: false,
      cert: '',
      key: ''
    }
  }
}

/**
 * 配置加载器，负责从文件加载配置
 */
export class ConfigLoader {
  private static readonly CONFIG_FILE_NAMES = [
    'ngate.config.js',
    'ngate.config.json',
    '.ngaterc',
    '.ngaterc.json',
    '.ngaterc.js'
  ];

  private static logger = Logger.getInstance();

  /**
   * 获取默认配置
   */
  public static getDefaultConfig(): ServerConfig {
    return MergeUtil.deepMerge({}, DEFAULT_CONFIG);
  }

  /**
   * 从指定路径加载配置文件
   * @param configPath 配置文件路径
   */
  public static loadConfigFromPath(configPath: string): Partial<ServerConfig> {
    if (!fs.existsSync(configPath)) {
      this.logger.error(`配置文件不存在: ${configPath}`);
      return {};
    }

    try {
      // 根据文件扩展名决定如何加载
      const ext = path.extname(configPath).toLowerCase();

      if (ext === '.js') {
        // 动态加载JS模块
        const config = require(path.resolve(configPath));
        this.logger.info(`已从文件加载配置: ${configPath}`);
        return config;
      } else if (ext === '.json' || !ext) {
        // 读取JSON文件或无扩展名文件
        const content = fs.readFileSync(configPath, 'utf-8');
        const config = JSON.parse(content);
        this.logger.info(`已从文件加载配置: ${configPath}`);
        return config;
      } else {
        this.logger.error(`不支持的配置文件格式: ${configPath}`);
        return {};
      }
    } catch (error) {
      this.logger.error(`加载配置文件失败: ${error instanceof Error ? error.message : String(error)}`);
      return {};
    }
  }

  /**
   * 自动搜索并加载配置文件
   */
  public static autoLoadConfig(): Partial<ServerConfig> {
    // 查找当前目录下的配置文件
    for (const fileName of this.CONFIG_FILE_NAMES) {
      const configPath = path.join(process.cwd(), fileName);
      if (fs.existsSync(configPath)) {
        this.logger.info(`发现配置文件: ${configPath}`);
        return this.loadConfigFromPath(configPath);
      }
    }

    this.logger.debug('未找到配置文件，使用默认配置');
    return {};
  }

  /**
   * 合并配置
   * @param baseConfig 基础配置
   * @param overrideConfig 覆盖配置
   */
  public static mergeConfigs(baseConfig: Partial<ServerConfig>, overrideConfig: Partial<ServerConfig>): ServerConfig {
    // 创建一个默认配置的副本
    const defaultConfig = this.getDefaultConfig();

    // 使用深度合并方法合并配置
    MergeUtil.deepMerge(defaultConfig, baseConfig);
    MergeUtil.deepMerge(defaultConfig, overrideConfig);

    return defaultConfig;
  }
}
